<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>俄罗斯方块</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
    <script>
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        primary: '#3B82F6',
                        secondary: '#10B981',
                        dark: '#1E293B',
                        light: '#F8FAFC',
                        tetris: {
                            i: '#06B6D4',
                            j: '#2563EB',
                            l: '#F59E0B',
                            o: '#FBBF24',
                            s: '#10B981',
                            t: '#8B5CF6',
                            z: '#EF4444'
                        }
                    },
                    fontFamily: {
                        game: ['"Press Start 2P"', 'cursive', 'sans-serif']
                    }
                }
            }
        }
    </script>
    <style type="text/tailwindcss">
        @layer utilities {
            .text-shadow {
                text-shadow: 2px 2px 0px rgba(0, 0, 0, 0.3);
            }
            .grid-bg {
                background-image: linear-gradient(#333 1px, transparent 1px),
                                linear-gradient(90deg, #333 1px, transparent 1px);
            }
            .pixel-corners {
                clip-path: polygon(
                    0% 4px, 4px 4px, 4px 0%, calc(100% - 4px) 0%, calc(100% - 4px) 4px, 100% 4px,
                    100% calc(100% - 4px), calc(100% - 4px) calc(100% - 4px), calc(100% - 4px) 100%,
                    4px 100%, 4px calc(100% - 4px), 0% calc(100% - 4px)
                );
            }
        }
    </style>
    <link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap" rel="stylesheet">
</head>
<body class="bg-gradient-to-br from-dark to-gray-800 min-h-screen flex flex-col items-center justify-center p-4 text-light">
    <div class="max-w-4xl w-full mx-auto flex flex-col md:flex-row gap-6 items-center md:items-start justify-center">
        <!-- 游戏标题 -->
        <div class="w-full text-center mb-4">
            <h1 class="text-[clamp(1.8rem,5vw,3rem)] font-game text-primary text-shadow animate-pulse">俄罗斯方块</h1>
        </div>
        
        <!-- 游戏区域 -->
        <div class="relative">
            <canvas id="tetrisCanvas" class="border-4 border-gray-700 bg-gray-900 pixel-corners shadow-lg"></canvas>
            
            <!-- 游戏暂停覆盖层 -->
            <div id="pauseOverlay" class="absolute inset-0 bg-dark/80 flex items-center justify-center hidden">
                <div class="text-center p-6">
                    <p class="font-game text-2xl mb-4 text-yellow-400">游戏暂停</p>
                    <p class="text-gray-300">按 P 继续</p>
                </div>
            </div>
            
            <!-- 游戏结束覆盖层 -->
            <div id="gameOverOverlay" class="absolute inset-0 bg-dark/80 flex items-center justify-center hidden">
                <div class="text-center p-6 bg-gray-800 border-2 border-red-500 rounded-lg">
                    <p class="font-game text-2xl mb-4 text-red-400">游戏结束</p>
                    <p class="text-xl mb-2">得分: <span id="finalScore">0</span></p>
                    <button id="restartBtn" class="mt-4 bg-primary hover:bg-primary/80 text-white py-2 px-4 rounded font-bold transition-all transform hover:scale-105">
                        重新开始
                    </button>
                </div>
            </div>
        </div>
        
        <!-- 游戏信息和控制区 -->
        <div class="w-full md:w-64 flex flex-col gap-4">
            <!-- 分数面板 -->
            <div class="bg-gray-800 border-2 border-gray-700 rounded-lg p-4 pixel-corners">
                <h2 class="text-center text-lg font-bold mb-2">分数</h2>
                <p id="score" class="text-3xl text-center font-game text-yellow-400">0</p>
            </div>
            
            <!-- 下一个方块预览 -->
            <div class="bg-gray-800 border-2 border-gray-700 rounded-lg p-4 pixel-corners">
                <h2 class="text-center text-lg font-bold mb-2">下一个</h2>
                <canvas id="nextPieceCanvas" class="mx-auto bg-gray-900"></canvas>
            </div>
            
            <!-- 控制按钮 -->
            <div class="grid grid-cols-3 gap-2">
                <div class="col-start-2">
                    <button id="rotateBtn" class="w-full bg-gray-700 hover:bg-gray-600 p-2 rounded">
                        <i class="fa fa-rotate-right text-xl"></i>
                    </button>
                </div>
                <div class="col-start-1">
                    <button id="leftBtn" class="w-full bg-gray-700 hover:bg-gray-600 p-2 rounded">
                        <i class="fa fa-arrow-left text-xl"></i>
                    </button>
                </div>
                <div class="col-start-2">
                    <button id="downBtn" class="w-full bg-gray-700 hover:bg-gray-600 p-2 rounded">
                        <i class="fa fa-arrow-down text-xl"></i>
                    </button>
                </div>
                <div class="col-start-3">
                    <button id="rightBtn" class="w-full bg-gray-700 hover:bg-gray-600 p-2 rounded">
                        <i class="fa fa-arrow-right text-xl"></i>
                    </button>
                </div>
            </div>
            
            <!-- 游戏控制 -->
            <div class="flex gap-2">
                <button id="startBtn" class="flex-1 bg-green-600 hover:bg-green-500 text-white py-2 px-4 rounded font-bold">
                    开始
                </button>
                <button id="pauseBtn" class="flex-1 bg-yellow-600 hover:bg-yellow-500 text-white py-2 px-4 rounded font-bold">
                    暂停
                </button>
            </div>
            
            <!-- 操作说明 -->
            <div class="bg-gray-800/50 border border-gray-700 rounded-lg p-3 text-sm">
                <h3 class="font-bold mb-1">操作说明:</h3>
                <p><span class="inline-block w-16">← → 键:</span> 左右移动</p>
                <p><span class="inline-block w-16">↑ 键:</span> 旋转</p>
                <p><span class="inline-block w-16">↓ 键:</span> 加速下落</p>
                <p><span class="inline-block w-16">空格:</span> 直接落地</p>
                <p><span class="inline-block w-16">P 键:</span> 暂停/继续</p>
            </div>
        </div>
    </div>

    <script>
        // 游戏配置
        const COLS = 10;
        const ROWS = 20;
        const BLOCK_SIZE = 30;
        const NEXT_PIECE_SIZE = 4;
        
        // 方块形状和颜色定义
        const SHAPES = {
            I: [
                [0, 0, 0, 0],
                [1, 1, 1, 1],
                [0, 0, 0, 0],
                [0, 0, 0, 0]
            ],
            J: [
                [1, 0, 0],
                [1, 1, 1],
                [0, 0, 0]
            ],
            L: [
                [0, 0, 1],
                [1, 1, 1],
                [0, 0, 0]
            ],
            O: [
                [1, 1],
                [1, 1]
            ],
            S: [
                [0, 1, 1],
                [1, 1, 0],
                [0, 0, 0]
            ],
            T: [
                [0, 1, 0],
                [1, 1, 1],
                [0, 0, 0]
            ],
            Z: [
                [1, 1, 0],
                [0, 1, 1],
                [0, 0, 0]
            ]
        };
        
        const COLORS = {
            I: '#06B6D4',    // 青色
            J: '#2563EB',    // 蓝色
            L: '#F59E0B',    // 橙色
            O: '#FBBF24',    // 黄色
            S: '#10B981',    // 绿色
            T: '#8B5CF6',    // 紫色
            Z: '#EF4444',    // 红色
            empty: '#1E293B', // 背景色
            border: '#334155' // 边框色
        };
        
        // 获取DOM元素
        const canvas = document.getElementById('tetrisCanvas');
        const ctx = canvas.getContext('2d');
        const nextPieceCanvas = document.getElementById('nextPieceCanvas');
        const nextCtx = nextPieceCanvas.getContext('2d');
        const scoreElement = document.getElementById('score');
        const finalScoreElement = document.getElementById('finalScore');
        const startBtn = document.getElementById('startBtn');
        const pauseBtn = document.getElementById('pauseBtn');
        const restartBtn = document.getElementById('restartBtn');
        const leftBtn = document.getElementById('leftBtn');
        const rightBtn = document.getElementById('rightBtn');
        const downBtn = document.getElementById('downBtn');
        const rotateBtn = document.getElementById('rotateBtn');
        const pauseOverlay = document.getElementById('pauseOverlay');
        const gameOverOverlay = document.getElementById('gameOverOverlay');
        
        // 设置画布尺寸
        canvas.width = COLS * BLOCK_SIZE;
        canvas.height = ROWS * BLOCK_SIZE;
        nextPieceCanvas.width = NEXT_PIECE_SIZE * BLOCK_SIZE;
        nextPieceCanvas.height = NEXT_PIECE_SIZE * BLOCK_SIZE;
        
        // 游戏状态
        let board = createEmptyBoard();
        let currentPiece = null;
        let nextPiece = null;
        let score = 0;
        let dropInterval = 1000; // 初始下落间隔(毫秒)
        let dropTimer = null;
        let isGameOver = false;
        let isPaused = false;
        
        // 创建空的游戏板
        function createEmptyBoard() {
            return Array(ROWS).fill().map(() => Array(COLS).fill(0));
        }
        
        // 随机生成新方块
        function createNewPiece() {
            const keys = Object.keys(SHAPES);
            const tetromino = keys[Math.floor(Math.random() * keys.length)];
            
            return {
                shape: SHAPES[tetromino],
                color: COLORS[tetromino],
                type: tetromino,
                x: Math.floor((COLS - SHAPES[tetromino][0].length) / 2),
                y: 0
            };
        }
        
        // 检查碰撞
        function checkCollision(piece, offsetX = 0, offsetY = 0) {
            for (let y = 0; y < piece.shape.length; y++) {
                for (let x = 0; x < piece.shape[y].length; x++) {
                    if (piece.shape[y][x]) {
                        const newX = piece.x + x + offsetX;
                        const newY = piece.y + y + offsetY;
                        
                        // 检查是否超出边界
                        if (newX < 0 || newX >= COLS || newY >= ROWS) {
                            return true;
                        }
                        
                        // 检查是否与已有方块碰撞
                        if (newY >= 0 && board[newY][newX]) {
                            return true;
                        }
                    }
                }
            }
            return false;
        }
        
        // 旋转方块
        function rotatePiece(piece) {
            // 创建旋转后的形状 (转置矩阵并反转每行)
            const rotated = piece.shape[0].map((_, index) => 
                piece.shape.map(row => row[index]).reverse()
            );
            
            const originalShape = piece.shape;
            piece.shape = rotated;
            
            // 如果旋转后碰撞，尝试墙踢 (wall kick)
            if (checkCollision(piece)) {
                // 尝试右移
                if (!checkCollision(piece, 1, 0)) {
                    piece.x += 1;
                } 
                // 尝试左移
                else if (!checkCollision(piece, -1, 0)) {
                    piece.x -= 1;
                } 
                // 尝试下移
                else if (!checkCollision(piece, 0, 1)) {
                    piece.y += 1;
                } 
                // 都不行则取消旋转
                else {
                    piece.shape = originalShape;
                }
            }
        }
        
        // 锁定当前方块到游戏板上
        function lockPiece() {
            for (let y = 0; y < currentPiece.shape.length; y++) {
                for (let x = 0; x < currentPiece.shape[y].length; x++) {
                    if (currentPiece.shape[y][x]) {
                        const newX = currentPiece.x + x;
                        const newY = currentPiece.y + y;
                        
                        // 如果方块顶部超出游戏区域，则游戏结束
                        if (newY < 0) {
                            gameOver();
                            return;
                        }
                        
                        board[newY][newX] = currentPiece.color;
                    }
                }
            }
            
            // 检查并消除已满的行
            clearLines();
            
            // 生成新方块
            currentPiece = nextPiece;
            nextPiece = createNewPiece();
            
            // 检查新方块是否立即碰撞
            if (checkCollision(currentPiece)) {
                gameOver();
            }
            
            draw();
        }
        
        // 消除已满的行
        function clearLines() {
            let linesCleared = 0;
            
            for (let y = ROWS - 1; y >= 0; y--) {
                if (board[y].every(cell => cell !== 0)) {
                    // 移除已满的行并在顶部添加新的空行
                    board.splice(y, 1);
                    board.unshift(Array(COLS).fill(0));
                    linesCleared++;
                    y++; // 检查新移到当前位置的行
                }
            }
            
            // 根据消除的行数增加分数
            if (linesCleared > 0) {
                // 分数计算: 1行=100, 2行=300, 3行=500, 4行=800
                const lineScores = [0, 100, 300, 500, 800];
                score += lineScores[linesCleared];
                scoreElement.textContent = score;
                
                // 随着分数增加，加快下落速度
                dropInterval = Math.max(100, 1000 - (score / 1000) * 500);
                restartDropTimer();
            }
        }
        
        // 绘制游戏
        function draw() {
            // 清空画布
            ctx.fillStyle = COLORS.empty;
            ctx.fillRect(0, 0, canvas.width, canvas.height);
            
            // 绘制网格线
            drawGrid();
            
            // 绘制已锁定的方块
            for (let y = 0; y < ROWS; y++) {
                for (let x = 0; x < COLS; x++) {
                    if (board[y][x]) {
                        drawBlock(ctx, x, y, board[y][x]);
                    }
                }
            }
            
            // 绘制当前方块
            if (currentPiece) {
                for (let y = 0; y < currentPiece.shape.length; y++) {
                    for (let x = 0; x < currentPiece.shape[y].length; x++) {
                        if (currentPiece.shape[y][x]) {
                            const drawX = currentPiece.x + x;
                            const drawY = currentPiece.y + y;
                            if (drawY >= 0) { // 只绘制可见的部分
                                drawBlock(ctx, drawX, drawY, currentPiece.color);
                            }
                        }
                    }
                }
            }
            
            // 绘制下一个方块预览
            drawNextPiece();
        }
        
        // 绘制网格线
        function drawGrid() {
            ctx.strokeStyle = COLORS.border;
            ctx.lineWidth = 0.5;
            
            // 绘制垂直线
            for (let x = 0; x <= COLS; x++) {
                ctx.beginPath();
                ctx.moveTo(x * BLOCK_SIZE, 0);
                ctx.lineTo(x * BLOCK_SIZE, canvas.height);
                ctx.stroke();
            }
            
            // 绘制水平线
            for (let y = 0; y <= ROWS; y++) {
                ctx.beginPath();
                ctx.moveTo(0, y * BLOCK_SIZE);
                ctx.lineTo(canvas.width, y * BLOCK_SIZE);
                ctx.stroke();
            }
        }
        
        // 绘制单个方块
        function drawBlock(context, x, y, color) {
            const xPos = x * BLOCK_SIZE;
            const yPos = y * BLOCK_SIZE;
            
            // 绘制方块主体
            context.fillStyle = color;
            context.fillRect(xPos, yPos, BLOCK_SIZE - 1, BLOCK_SIZE - 1);
            
            // 绘制高光效果
            context.fillStyle = rgbaFromHex(color, 0.3);
            context.fillRect(xPos, yPos, BLOCK_SIZE - 1, (BLOCK_SIZE - 1) / 2);
            
            // 绘制阴影效果
            context.fillStyle = rgbaFromHex(color, 0.7);
            context.fillRect(xPos, yPos + (BLOCK_SIZE - 1) / 2, BLOCK_SIZE - 1, (BLOCK_SIZE - 1) / 2);
        }
        
        // 绘制下一个方块预览
        function drawNextPiece() {
            // 清空预览画布
            nextCtx.fillStyle = COLORS.empty;
            nextCtx.fillRect(0, 0, nextPieceCanvas.width, nextPieceCanvas.height);
            
            // 绘制预览网格
            nextCtx.strokeStyle = COLORS.border;
            nextCtx.lineWidth = 0.5;
            
            // 绘制垂直线
            for (let x = 0; x <= NEXT_PIECE_SIZE; x++) {
                nextCtx.beginPath();
                nextCtx.moveTo(x * BLOCK_SIZE, 0);
                nextCtx.lineTo(x * BLOCK_SIZE, nextPieceCanvas.height);
                nextCtx.stroke();
            }
            
            // 绘制水平线
            for (let y = 0; y <= NEXT_PIECE_SIZE; y++) {
                nextCtx.beginPath();
                nextCtx.moveTo(0, y * BLOCK_SIZE);
                nextCtx.lineTo(nextPieceCanvas.width, y * BLOCK_SIZE);
                nextCtx.stroke();
            }
            
            // 绘制下一个方块
            if (nextPiece) {
                const offsetX = Math.floor((NEXT_PIECE_SIZE - nextPiece.shape[0].length) / 2);
                const offsetY = Math.floor((NEXT_PIECE_SIZE - nextPiece.shape.length) / 2);
                
                for (let y = 0; y < nextPiece.shape.length; y++) {
                    for (let x = 0; x < nextPiece.shape[y].length; x++) {
                        if (nextPiece.shape[y][x]) {
                            drawBlock(nextCtx, x + offsetX, y + offsetY, nextPiece.color);
                        }
                    }
                }
            }
        }
        
        // 辅助函数: 将十六进制颜色转换为带透明度的rgba
        function rgbaFromHex(hex, alpha) {
            const r = parseInt(hex.slice(1, 3), 16);
            const g = parseInt(hex.slice(3, 5), 16);
            const b = parseInt(hex.slice(5, 7), 16);
            return `rgba(${r}, ${g}, ${b}, ${alpha})`;
        }
        
        // 移动方块
        function movePiece(dx, dy) {
            if (isPaused || isGameOver) return;
            
            if (!checkCollision(currentPiece, dx, dy)) {
                currentPiece.x += dx;
                currentPiece.y += dy;
                draw();
                return true;
            } else if (dy > 0) {
                // 如果下移时碰撞，锁定方块
                lockPiece();
                return false;
            }
            return false;
        }
        
        // 方块直接落地
        function hardDrop() {
            if (isPaused || isGameOver) return;
            
            let dropped = 0;
            while (movePiece(0, 1)) {
                dropped++;
            }
            // 为硬降落增加额外分数
            score += Math.floor(dropped / 2);
            scoreElement.textContent = score;
        }
        
        // 开始下落计时器
        function startDropTimer() {
            if (dropTimer) clearInterval(dropTimer);
            
            dropTimer = setInterval(() => {
                if (!isPaused && !isGameOver) {
                    movePiece(0, 1);
                }
            }, dropInterval);
        }
        
        // 重启下落计时器
        function restartDropTimer() {
            clearInterval(dropTimer);
            startDropTimer();
        }
        
        // 开始游戏
        function startGame() {
            board = createEmptyBoard();
            score = 0;
            isGameOver = false;
            isPaused = false;
            scoreElement.textContent = score;
            
            // 初始化方块
            currentPiece = createNewPiece();
            nextPiece = createNewPiece();
            
            // 隐藏覆盖层
            pauseOverlay.classList.add('hidden');
            gameOverOverlay.classList.add('hidden');
            
            // 开始下落
            startDropTimer();
            
            // 绘制游戏
            draw();
        }
        
        // 暂停/继续游戏
        function togglePause() {
            if (isGameOver) return;
            
            isPaused = !isPaused;
            
            if (isPaused) {
                clearInterval(dropTimer);
                pauseOverlay.classList.remove('hidden');
            } else {
                startDropTimer();
                pauseOverlay.classList.add('hidden');
            }
        }
        
        // 游戏结束
        function gameOver() {
            isGameOver = true;
            clearInterval(dropTimer);
            finalScoreElement.textContent = score;
            gameOverOverlay.classList.remove('hidden');
        }
        
        // 事件监听 - 键盘控制
        document.addEventListener('keydown', (e) => {
            if (isGameOver) return;
            
            switch (e.key) {
                case 'ArrowLeft':
                    movePiece(-1, 0);
                    break;
                case 'ArrowRight':
                    movePiece(1, 0);
                    break;
                case 'ArrowDown':
                    movePiece(0, 1);
                    break;
                case 'ArrowUp':
                    rotatePiece(currentPiece);
                    draw();
                    break;
                case ' ': // 空格键
                    hardDrop();
                    break;
                case 'p':
                case 'P':
                    togglePause();
                    break;
            }
        });
        
        // 事件监听 - 按钮控制
        startBtn.addEventListener('click', startGame);
        pauseBtn.addEventListener('click', togglePause);
        restartBtn.addEventListener('click', startGame);
        leftBtn.addEventListener('click', () => movePiece(-1, 0));
        rightBtn.addEventListener('click', () => movePiece(1, 0));
        downBtn.addEventListener('click', () => movePiece(0, 1));
        rotateBtn.addEventListener('click', () => {
            rotatePiece(currentPiece);
            draw();
        });
        
        // 初始化游戏
        window.addEventListener('load', () => {
            // 绘制初始界面
            board = createEmptyBoard();
            nextPiece = createNewPiece();
            drawNextPiece();
        });
    </script>
</body>
</html>
